![[Forecast] 電力使用量のデータで予測と実績を比較してみました](https://devio2023-media.developers.io/wp-content/uploads/2022/08/amazon-forecast.png)
[Forecast] 電力使用量のデータで予測と実績を比較してみました
1 はじめに
CX 事業本部デリバリー部の平内(SIN)です。
Amazon Forecast は、統計アルゴリズムと機械学習アルゴリズムによる、時系列予測を実現するフルマネージドサービスですが、初めて利用する方などを対象とした、非常に分かりやすいハンズオンが公開されています。
Amazon Forecast ハンズオン
ハンズオンでは、1 年分の電力使用量データを使用して、次の 36 時間の使用量を予測しています。
https://pages.awscloud.com/rs/112-TZM-766/images/201912-AmazonForecastHandson.pdf
上記を進めることで、手順を理解するのは、十分なのですが、最後に、予測された結果を見て、これは、実際の結果と比較してどうなんだろう?って少し気になってしまいました。
そこで、今回は、同じ手順になりますが、11 ヶ月分をデータセットとして学習し、残りの 1 ヶ月分で、推論結果と比較してみました。
2 電力使用量データ
ハンズオンで使用されている電力使用量データは、400 家庭分(client_0 から client_399)の 2014/01/01 00:00 から 2015/01/01 00:00 までの1年分のデータとなっています。
400 種類のデータだと、ちょっと分かりにくいので、一部抜粋してみると次のようになります。
- 2014/12/01〜2014/12/09
- 1h 間隔
- client_0, client_1, client_2, client_3, client_4, client_5
上記では、client_0 と client_2 が、比較的小さな数字でよく見えないので、大きなデータを外してみるとこんな感じです。
- 2014/12/01〜2014/12/09
- 1h 間隔
- client_0, client_1, client_2
client_0 は、cleint_2 は、他のデータに比較して、非常に値が小さいことが分かります。実は、やってみての実感なのですが、値 0 が多数存在したり、変化量が小さい場合、予測が難しいと思いました。
ちなみに、1年を通してみると季節性のあるデータもあるようです。
- 2014/12/01〜2014/12/09
- 1w 間隔
- client_103, client_113
client_103 は、夏場(8 月を中心)に多く、逆に、client_113 は、少なくなっています。
この後の作業は、client_1,client_3,client_4,clinet_5 の 4 種類をターゲットにしてみます。(ハンズオンで最後にグラフを表示しているのは、client_1)
3 データの抽出
最初に、2014 年(1 年分)のデータから 11 ヶ月分を切り出します。 プログラムでは、単純に日時カラムの日付部分を文字列比較しているだけです。
date_filter.py
def main(): start_date = '2014-01-01' end_date = '2014-11-30' input_filename = 'electricityusagedata.csv' output_filename = 'electricityusagedata_{}_{}.csv'.format(start_date.replace('-',''), end_date.replace('-','')) output_text = '' with open(input_filename) as f: lines = f.readlines() for line in lines: tmp = line.replace('\n','').split(',') date_str = tmp[0][0:10] # 日時のカラムから日付部分を抽出 # 条件にマッチした(期間内)ものだけ出力対象にする if(start_date <= date_str and date_str<= end_date): output_text += line with open(output_filename, mode='w') as f: f.write(output_text) if __name__ == "__main__": main()
electricityusagedata.csv(元データ)
157.2M byte
2014-01-01 01:00:00,2.53807106598985,client_0 2014-01-01 01:00:00,23.648648648648624,client_1 2014-01-01 01:00:00,0.0,client_2 ・・・略・・・ 2015-01-01 00:00:00,150.25041736227024,client_367 2015-01-01 00:00:00,664.7727272727273,client_368 2015-01-01 00:00:00,6810.81081081081,client_369
electricityusagedata_20140101_20141130.csv(切り出したデータ)
137.2M byte
2014-01-01 01:00:00,2.53807106598985,client_0 2014-01-01 01:00:00,23.648648648648624,client_1 2014-01-01 01:00:00,0.0,client_2 ・・・略・・・ 2014-11-30 23:00:00,51.75292153589315,client_367 2014-11-30 23:00:00,661.6568914956013,client_368 2014-11-30 23:00:00,17702.7027027027,client_369
4 データセット
切り出した、electricityusagedata_20140101_20141130.csvを S3 に置いて、データセットグループを作成します。
ドメインは、Customとしています。
スキーマーをデータのカラムに一致させ、周期を 1 時間としました。
格納先の S3 バケットを指定して、データセットを作成しています。
5 学習
AWS コンソールから学習を進めると、自動的にAutoMLとなります。(以前は、アルゴリズムの選択が可能でした)
AutoML だと、少し時間とお金ががかかってしまうので、今回は、SDK を使用して、機械学習(Deep_AR_Plus)で PHO オフとしています。
また、予測タイプは、0.5 のみ、予測間隔 1 時間、予測数は9日分です。
import boto3 session = boto3.Session(region_name='ap-northeast-1') forecast = session.client(service_name='forecast') # Setting freq = "1H" # 予測間隔 forecast_horizon = 216 # 予測数(データセットの1/3以内) 24*9=216 performAutoML = False # AutoMLの有効化 performHPO = False # ハイパーパラメータ最適化 algorithm = 'Deep_AR_Plus' forecastTypes = ["0.50"] # 予測タイプ(分位数) 0.01から0.99 まで最大5つ account = "xxxxxxxxxxxx" dataset_group_name = "electricityusagedata_20140101_20141130" predictor_name = "train_{}_{}_{}".format(dataset_group_name, forecast_horizon, algorithm) predictor_arn = "arn:aws:forecast:ap-northeast-1:{}:predictor/{}".format( account, predictor_name) dataset_group_arn = "arn:aws:forecast:ap-northeast-1:{}:dataset-group/{}".format( account, dataset_group_name) # Traning create_predictor_response = forecast.create_predictor(PredictorName=predictor_name, AlgorithmArn="arn:aws:forecast:::algorithm/{}".format( algorithm), ForecastHorizon=forecast_horizon, ForecastTypes=forecastTypes, PerformAutoML=performAutoML, PerformHPO=performHPO, InputDataConfig={ "DatasetGroupArn": dataset_group_arn, }, FeaturizationConfig={"ForecastFrequency": freq}) status = forecast.describe_predictor(PredictorArn=predictor_arn) print(status["Status"])
6 予測
予測は、対象をSelected Itemsとして、下記のselected_items.csvを指定しています。(All Items とすると、400 個(client_0〜cleint_399)全てのポイント出力となり利用費が上がってしまうので、注意が必要です)
selected_items.csv
client_1 client_3 client_4 clinet_5
結果をダウンロードして元のデータと比較してみました。
以下が凡例の意になります。
client_1 元のデータ P_client_1 予測データ
- client_1 では、予測結果が、全体に大きな値になっていますが、増減については、殆ど追従しているように見えます。
- client_3,client_4,client_5 は、要求される精度にもよりますが、十分に予測できているように思えます。
7 最後に
今回は、すでに結果の分かっているデータを Forecast で予測し、実績値と推論値の比較を行ってみました。 このような作業を、いくつか繰り返し、作業要領の勘所を掴めたらと考えています。